package com.xpec.c4.service.module.task;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.ms.service.module.datacenterlite.CentralDataAsync;
import com.xpec.c4.game.utility.GUID;
import com.xpec.c4.service.module.BasicServiceModule;


/**
 * 
 * @author yangbingyan
 *
 */
public abstract class TaskAsyncCommand extends TaskObject {

	/**
	 * 有指定 key 的話會用 key 來分配到對應的 queue, 將執行的負擔分散
	 */
	public GUID key = null;
	
	/**
	 * 默認使用第0條 task Queue
	 */
	private int queueID = 0;

	/**
	 * queue id 是否有被變更過
	 */
	private boolean queueIdChanged = false;

	/**
	 * 所屬module
	 */
	public BasicServiceModule moduleServer;
	
	/**
	 * 目前所在的 module server
	 * <p>
	 * 這裡的值會在執行時期系統自動填入，自行在這邊填值的話會可能會在執行過程中被覆蓋掉。
	 */
	private BasicServiceModule currentModuleServer;
	
	/**
	 * processer 回呼函式名稱
	 */
	protected String callbackMethod;
	
	protected Class<?> callbackclass;
	
	public Class<?> getCallbackclass() {
		return callbackclass;
	}

	public void setCallbackclass(Class<?> callbackclass) {
		this.callbackclass = callbackclass;
	}

	public String getCallbackMethod() 
	{
		return callbackMethod;
	}

	public void setCallbackMethod(String callbackMethod) 
	{
		this.callbackMethod = callbackMethod;
	}
	
	/**
	 * 异步调用
	 */
	public abstract void asyncExecute() throws Exception;

	/**
	 * 取得 task 的真正名稱, 如果是有層層包裝的 task 會回傳真正的名稱
	 */
	public String getRealTaskName() {
		if (this instanceof CentralDataAsync) {
			CentralDataAsync centralAsync = (CentralDataAsync) this;
			return centralAsync.getCommand().getClass().getSimpleName();
		}

		return this.getClass().getSimpleName();
	}
	
	/**
	 * 
	 */
	@Override
	public void procTask() throws Exception 
	{
		execute();
	}
	
	
	/**
	 * 執行回呼processer call back method
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	public void executeProcCallBack() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
	{
		Method m  = (this.moduleServer.getBasicprocesser()).getClass().getMethod(callbackMethod, new Class[]{callbackclass});
		m.invoke( (this.moduleServer.getBasicprocesser()), new Object[]{this});
	}

	public BasicServiceModule getCurrentModuleServer() {
		return currentModuleServer;
	}

	public void setCurrentModuleServer(BasicServiceModule currentModuleServer) {
		this.currentModuleServer = currentModuleServer;
	}

	public int getQueueID() {
		return queueID;
	}

	public void setQueueID(int queueID) {
		this.queueID = queueID;
		this.queueIdChanged = true;
	}

	public boolean isQueueIdChanged() {
		return queueIdChanged;
	}

}
